package rexsee.core.application;

import java.io.File;
import java.util.BitSet;
import java.util.Iterator;
import java.util.List;

import rexsee.core.browser.Browser;
import rexsee.core.browser.clazz.JavascriptInterface;
import android.app.ActivityManager;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.AuthorityEntry;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.os.Debug;
import android.os.PatternMatcher;

public class RexseeApplicationManager implements JavascriptInterface {

	public static final String INTERFACE_NAME = "ApplicationManager";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return this;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeApplicationManager(childBrowser);
	}

	public static final int MAX_NUM = 999;

	private final Browser mBrowser;
	private final Context mContext;

	public RexseeApplicationManager(Browser browser) {
		mBrowser = browser;
		mContext = browser.getContext();
	}

	public static String getJsonApplicationInfo_(Context mContext, ApplicationInfo applicationInfo) {
		PackageManager pm = mContext.getPackageManager();
		String rtn = "{";
		rtn += "\"packageName\":\"" + applicationInfo.packageName + "\"";
		rtn += ",\"uid\":" + applicationInfo.uid;
		rtn += ",\"label\":\"" + applicationInfo.loadLabel(pm) + "\"";
		rtn += ",\"name\":\"" + applicationInfo.name + "\"";
		rtn += ",\"processName\":\"" + applicationInfo.processName + "\"";
		rtn += ",\"className\":\"" + applicationInfo.className + "\"";
		rtn += ",\"description\":\"" + applicationInfo.loadDescription(pm) + "\"";
		rtn += ",\"manageSpaceActivityName\":\"" + applicationInfo.manageSpaceActivityName + "\"";
		rtn += ",\"publicSourceDir\":\"" + applicationInfo.publicSourceDir + "\"";
		rtn += ",\"sourceDir\":\"" + applicationInfo.sourceDir + "\"";
		rtn += ",\"dataDir\":\"" + applicationInfo.dataDir + "\"";
		rtn += ",\"flags\":\"" + new BitSet(applicationInfo.flags).toString() + "\"";
		rtn += ",\"permission\":\"" + applicationInfo.permission + "\"";
		rtn += ",\"taskAffinity\":\"" + applicationInfo.taskAffinity + "\"";
		rtn += ",\"targetSdkVersion\":" + applicationInfo.targetSdkVersion;
		rtn += ",\"enabled\":" + ((applicationInfo.enabled) ? "true" : "false");
		rtn += "}";
		return rtn;
	}
	public static String getJsonActivityInfo_(Context mContext, ActivityInfo activityInfo) {
		String rtn = "{";
		rtn += "\"name\":\"" + activityInfo.name + "\"";
		rtn += ",\"label\":\"" + activityInfo.loadLabel(mContext.getPackageManager()) + "\"";
		rtn += ",\"packageName\":\"" + activityInfo.packageName + "\"";
		rtn += ",\"processName\":\"" + activityInfo.processName + "\"";
		rtn += ",\"launchMode\":\"" + getLaunchMode_(activityInfo.launchMode) + "\"";
		rtn += ",\"permission\":\"" + activityInfo.permission + "\"";
		rtn += ",\"screenOrientation\":\"" + getScreenOrientation_(activityInfo.screenOrientation) + "\"";
		rtn += ",\"targetActivity\":\"" + activityInfo.targetActivity + "\"";
		rtn += ",\"taskAffinity\":\"" + activityInfo.taskAffinity + "\"";
		rtn += ",\"enabled\":" + ((activityInfo.enabled) ? "true" : "false");
		rtn += ",\"exported\":" + ((activityInfo.exported) ? "true" : "false");
		rtn += "}";
		return rtn;
	}
	public static String getJsonProviderInfo_(Context mContext, ProviderInfo providerInfo) {
		String rtn = "{";
		rtn += "\"name\":\"" + providerInfo.name + "\"";
		rtn += ",\"label\":\"" + providerInfo.loadLabel(mContext.getPackageManager()) + "\"";
		rtn += ",\"packageName\":\"" + providerInfo.packageName + "\"";
		rtn += ",\"processName\":\"" + providerInfo.processName + "\"";
		rtn += ",\"authority\":\"" + providerInfo.authority + "\"";
		rtn += ",\"readPermission\":\"" + providerInfo.readPermission + "\"";
		rtn += ",\"writePermission\":\"" + providerInfo.writePermission + "\"";
		rtn += ",\"enabled\":" + ((providerInfo.enabled) ? "true" : "false");
		rtn += ",\"exported\":" + ((providerInfo.exported) ? "true" : "false");
		rtn += "}";
		return rtn;
	}
	public static String getJsonServiceInfo_(Context mContext, ServiceInfo serviceInfo) {
		String rtn = "{";
		rtn += "\"name\":\"" + serviceInfo.name + "\"";
		rtn += ",\"label\":\"" + serviceInfo.loadLabel(mContext.getPackageManager()) + "\"";
		rtn += ",\"packageName\":\"" + serviceInfo.packageName + "\"";
		rtn += ",\"processName\":\"" + serviceInfo.processName + "\"";
		rtn += ",\"permission\":\"" + serviceInfo.permission + "\"";
		rtn += ",\"enabled\":" + ((serviceInfo.enabled) ? "true" : "false");
		rtn += ",\"exported\":" + ((serviceInfo.exported) ? "true" : "false");
		rtn += "}";
		return rtn;
	}
	public static String getJsonPermissionInfo_(Context mContext, PermissionInfo permissionInfo) {
		String rtn = "{";
		rtn += "\"name\":\"" + permissionInfo.name + "\"";
		rtn += ",\"description\":\"" + permissionInfo.loadDescription(mContext.getPackageManager()) + "\"";
		rtn += ",\"protectionLevel\":\"" + getPermissionProtectionLevel_(permissionInfo.protectionLevel) + "\"";
		rtn += ",\"group\":\"" + permissionInfo.group + "\"";
		rtn += "}";
		return rtn;
	}
	public static String getJsonIntentFilter_(IntentFilter filter) {

		String rtn = "{";

		rtn += "\"actions\":[";
		for (int i = 0; i < filter.countActions(); i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + filter.getAction(i) + "\"";
		}
		rtn += "]";

		rtn += ",\"categories\":[";
		for (int i = 0; i < filter.countCategories(); i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + filter.getCategory(i) + "\"";
		}
		rtn += "]";

		rtn += ",\"dataSchemes\":[";
		for (int i = 0; i < filter.countDataSchemes(); i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + filter.getDataScheme(i) + "\"";
		}
		rtn += "]";

		rtn += ",\"dataTypes\":[";
		for (int i = 0; i < filter.countDataTypes(); i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + filter.getDataType(i) + "\"";
		}
		rtn += "]";

		rtn += ",\"dataAuthorities\":[";
		for (int i = 0; i < filter.countDataAuthorities(); i++) {
			if (i > 0) rtn += ",";
			AuthorityEntry authority = filter.getDataAuthority(i);
			rtn += "{";
			rtn += "\"host\":\"" + authority.getHost() + "\"";
			rtn += ",\"port\":" + authority.getPort();
			rtn += "}";
		}
		rtn += "]";

		rtn += ",\"dataPaths\":[";
		for (int i = 0; i < filter.countDataPaths(); i++) {
			if (i > 0) rtn += ",";
			PatternMatcher pattern = filter.getDataPath(i);
			rtn += "{";
			rtn += "\"path\":\"" + pattern.getPath() + "\"";
			rtn += ",\"type\":\"" + getPatternMacherType_(pattern.getType()) + "\"";
			rtn += "}";
		}
		rtn += "]";

		rtn += ",\"priority\":" + filter.getPriority();
		rtn += "}";

		return rtn;

	}

	public static String getPatternMacherType_(int type) {
		switch (type) {
			case PatternMatcher.PATTERN_LITERAL :
				return "PATTERN_LITERAL";
			case PatternMatcher.PATTERN_PREFIX :
				return "PATTERN_PREFIX";
			case PatternMatcher.PATTERN_SIMPLE_GLOB :
				return "PATTERN_SIMPLE_GLOB";
			default :
				return "PATTERN_LITERAL";
		}
	}
	public static String getPermissionProtectionLevel_(int level) {
		switch (level) {
			case PermissionInfo.PROTECTION_DANGEROUS :
				return "PROTECTION_DANGEROUS";
			case PermissionInfo.PROTECTION_NORMAL :
				return "PROTECTION_NORMAL";
			case PermissionInfo.PROTECTION_SIGNATURE :
				return "PROTECTION_SIGNATURE";
			case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM :
				return "PROTECTION_SIGNATURE_OR_SYSTEM";
			default :
				return "PROTECTION_NORMAL";
		}
	}
	public static String getScreenOrientation_(int screenOritation) {
		switch (screenOritation) {
			case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED :
				return "SCREEN_ORIENTATION_UNSPECIFIED";
			case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE :
				return "SCREEN_ORIENTATION_LANDSCAPE";
			case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
				return "SCREEN_ORIENTATION_PORTRAIT";
			case ActivityInfo.SCREEN_ORIENTATION_USER :
				return "SCREEN_ORIENTATION_USER";
			case ActivityInfo.SCREEN_ORIENTATION_BEHIND :
				return "SCREEN_ORIENTATION_BEHIND";
			case ActivityInfo.SCREEN_ORIENTATION_SENSOR :
				return "SCREEN_ORIENTATION_SENSOR";
			case ActivityInfo.SCREEN_ORIENTATION_NOSENSOR :
				return "SCREEN_ORIENTATION_NOSENSOR";
			default :
				return "SCREEN_ORIENTATION_UNSPECIFIED";
		}
	}
	public static String getLaunchMode_(int launchMode) {
		switch (launchMode) {
			case ActivityInfo.LAUNCH_MULTIPLE :
				return "LAUNCH_MULTIPLE";
			case ActivityInfo.LAUNCH_SINGLE_INSTANCE :
				return "LAUNCH_SINGLE_INSTANCE";
			case ActivityInfo.LAUNCH_SINGLE_TASK :
				return "LAUNCH_SINGLE_TASK";
			case ActivityInfo.LAUNCH_SINGLE_TOP :
				return "LAUNCH_SINGLE_TOP";
			default :
				return "LAUNCH_MULTIPLE";
		}
	}
	public static String getProcessImportance_(int importance) {
		switch (importance) {
			case RunningAppProcessInfo.IMPORTANCE_BACKGROUND :
				return "IMPORTANCE_BACKGROUND";
			case RunningAppProcessInfo.IMPORTANCE_EMPTY :
				return "IMPORTANCE_EMPTY";
			case RunningAppProcessInfo.IMPORTANCE_FOREGROUND :
				return "IMPORTANCE_FOREGROUND";
			case RunningAppProcessInfo.IMPORTANCE_SERVICE :
				return "IMPORTANCE_SERVICE";
			case RunningAppProcessInfo.IMPORTANCE_VISIBLE :
				return "IMPORTANCE_VISIBLE";
			default :
				return "unknown";
		}
	}
	public static String getProcessImportanceReason_(int reasonCode) {
		switch (reasonCode) {
			case RunningAppProcessInfo.REASON_PROVIDER_IN_USE :
				return "REASON_PROVIDER_IN_USE";
			case RunningAppProcessInfo.REASON_SERVICE_IN_USE :
				return "REASON_SERVICE_IN_USE";
			default :
				return "unknown";
		}
	}

	public static String getJsonInfoForProcessInfo_(Context mContext, RunningAppProcessInfo processInfo) {
		String rtn = "{";
		rtn += "\"processName\":\"" + processInfo.processName + "\"";
		rtn += ",\"pid\":" + processInfo.pid;
		rtn += ",\"uid\":" + processInfo.uid;
		rtn += ",\"importance\":\"" + getProcessImportance_(processInfo.importance) + "\"";
		rtn += ",\"iru\":" + processInfo.lru;
		rtn += ",\"importanceReason\":\"" + getProcessImportanceReason_(processInfo.importanceReasonCode) + "\"";
		rtn += ",\"importanceReasonPid\":" + processInfo.importanceReasonPid;
		if (processInfo.importanceReasonComponent == null) {
			rtn += ",\"importanceReasonPackageName\":\"\"";
			rtn += ",\"importanceReasonClassName\":\"\"";
			rtn += ",\"importanceReasonShortClassName\":\"\"";
		} else {
			rtn += ",\"importanceReasonPackageName\":\"" + processInfo.importanceReasonComponent.getPackageName() + "\"";
			rtn += ",\"importanceReasonClassName\":\"" + processInfo.importanceReasonComponent.getClassName() + "\"";
			rtn += ",\"importanceReasonShortClassName\":\"" + processInfo.importanceReasonComponent.getShortClassName() + "\"";
		}
		String pkg = "";
		if (processInfo.pkgList != null) {
		} else {
			for (int i = 0; i < processInfo.pkgList.length; i++) {
				if (i != 0) pkg += ",";
				pkg += processInfo.pkgList[i];
			}
		}
		rtn += ",\"packageList\":\"" + pkg + "\"";
		rtn += "}";
		return rtn;
	}
	public static ApplicationInfo getApplicationInfoByProcessName_(Context mContext, String processName) {
		if (processName == null) return null;
		PackageManager pm = mContext.getPackageManager();
		List<ApplicationInfo> ais = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
		Iterator<ApplicationInfo> iterator = ais.iterator();
		while (iterator.hasNext()) {
			ApplicationInfo appInfo = iterator.next();
			if (processName.equals(appInfo.processName)) return appInfo;
		}
		return null;
	}
	public static long getSize_(Context mContext, String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			ApplicationInfo info = pm.getApplicationInfo(packageName, PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			File file = new File(info.sourceDir);
			if (file.canRead()) return file.length();
			else return -1;
		} catch (NameNotFoundException e) {
			return -1;
		}
	}

	// JavaScript Interface

	//Static information
	public String getInstalledApplications() {
		PackageManager pm = mContext.getPackageManager();
		List<ApplicationInfo> ais = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
		Iterator<ApplicationInfo> iterator = ais.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			if (!rtn.equals("")) rtn += ",";
			rtn += getJsonApplicationInfo_(mContext, iterator.next());
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public boolean isSafeMode() {
		return mContext.getPackageManager().isSafeMode();
	}
	public String getNameForUid(int uid) {
		PackageManager pm = mContext.getPackageManager();
		return pm.getNameForUid(uid);
	}
	public String getPackagesForUid(int uid) {
		PackageManager pm = mContext.getPackageManager();
		String[] packages = pm.getPackagesForUid(uid);
		String rtn = "";
		for (int i = 0; i < packages.length; i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + packages[i] + "\"";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public String getAllPermissionGroupInfo() {
		PackageManager pm = mContext.getPackageManager();
		List<PermissionGroupInfo> info = pm.getAllPermissionGroups(0);
		Iterator<PermissionGroupInfo> iterator = info.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			PermissionGroupInfo gInfo = iterator.next();
			if (!rtn.equals("")) rtn += ",";
			rtn += "{";
			rtn += "\"name\":\"" + gInfo.name + "\"";
			rtn += ",\"description\":\"" + gInfo.loadDescription(pm) + "\"";
			rtn += "}";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public String getAllPermissionsByGroup(String groupName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			List<PermissionInfo> permissions = pm.queryPermissionsByGroup(groupName, 0);
			Iterator<PermissionInfo> iterator = permissions.iterator();
			String rtn = "";
			while (iterator.hasNext()) {
				if (!rtn.equals("")) rtn += ",";
				rtn += getJsonPermissionInfo_(mContext, iterator.next());
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "[]";
		}
	}
	public String getSystemAvailableFeatures() {
		PackageManager pm = mContext.getPackageManager();
		FeatureInfo[] features = pm.getSystemAvailableFeatures();
		String rtn = "";
		for (int i = 0; i < features.length; i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + features[i].name + "\"";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public String getSystemSharedLibraryNames() {
		PackageManager pm = mContext.getPackageManager();
		String[] names = pm.getSystemSharedLibraryNames();
		String rtn = "";
		for (int i = 0; i < names.length; i++) {
			if (i > 0) rtn += ",";
			rtn += "\"" + names[i] + "\"";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public String getAllContentProviders() {
		PackageManager pm = mContext.getPackageManager();
		List<ProviderInfo> providers = pm.queryContentProviders(null, 0, 0);
		if (providers == null) return "[]";
		Iterator<ProviderInfo> iterator = providers.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			if (!rtn.equals("")) rtn += ",";
			rtn += getJsonProviderInfo_(mContext, iterator.next());
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}

	//Runtime information
	public int getRunningAppNumber() {
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();
		return raps.size();
	}
	public String getRunningAppProcesses() {
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();
		Iterator<RunningAppProcessInfo> iterator = raps.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			if (!rtn.equals("")) rtn += ",";
			rtn += getJsonInfoForProcessInfo_(mContext, iterator.next());
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public int getRunningTaskNumber() {
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> tasks = am.getRunningTasks(MAX_NUM);
		return tasks.size();
	}
	public String getRunningTasks() {
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> tasks = am.getRunningTasks(MAX_NUM);
		Iterator<RunningTaskInfo> iterator = tasks.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			RunningTaskInfo tInfo = iterator.next();
			if (!rtn.equals("")) rtn += ",";
			rtn += "{";
			rtn += "\"id\":" + tInfo.id;
			rtn += ",\"numActivities\":" + tInfo.numActivities;
			rtn += ",\"numRunning\":" + tInfo.numRunning;
			rtn += ",\"baseActivity\":{";
			ComponentName baseComponent = tInfo.baseActivity;
			rtn += "\"packageName\":\"" + baseComponent.getPackageName() + "\"";
			rtn += ",\"className\":\"" + baseComponent.getClassName() + "\"";
			rtn += ",\"shortClassName\":\"" + baseComponent.getShortClassName() + "\"";
			rtn += "}";
			rtn += ",\"topActivity\":{";
			ComponentName topComponent = tInfo.topActivity;
			rtn += "\"packageName\":\"" + topComponent.getPackageName() + "\"";
			rtn += ",\"className\":\"" + topComponent.getClassName() + "\"";
			rtn += ",\"shortClassName\":\"" + topComponent.getShortClassName() + "\"";
			rtn += "}";
			rtn += ",\"description\":\"" + tInfo.description + "\"";
			rtn += "}";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public int getRunningServiceNumber() {
		ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningServiceInfo> services = activityManager.getRunningServices(MAX_NUM);
		return services.size();
	}
	public String getRunningServices() {
		ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningServiceInfo> services = activityManager.getRunningServices(MAX_NUM);
		Iterator<RunningServiceInfo> iterator = services.iterator();
		String rtn = "";
		while (iterator.hasNext()) {
			RunningServiceInfo sInfo = iterator.next();
			if (!rtn.equals("")) rtn += ",";
			rtn += "{";
			rtn += "\"pid\":" + sInfo.pid;
			rtn += ",\"processName\":\"" + sInfo.process + "\"";
			rtn += ",\"activeSince\":" + sInfo.activeSince;
			rtn += ",\"restarting\":" + sInfo.restarting;
			rtn += ",\"clientCount\":" + sInfo.clientCount;
			rtn += ",\"crashCount\":" + sInfo.crashCount;
			rtn += ",\"lastActivityTime\":" + sInfo.lastActivityTime;
			rtn += ",\"clientPackage\":\"" + sInfo.clientPackage + "\"";
			rtn += ",\"uid\":" + sInfo.uid;
			rtn += ",\"foreground\":" + ((sInfo.foreground) ? "true" : "false");
			rtn += ",\"started\":" + ((sInfo.started) ? "true" : "false");
			ComponentName component = sInfo.service;
			rtn += ",\"packageName\":\"" + component.getPackageName() + "\"";
			rtn += ",\"className\":\"" + component.getClassName() + "\"";
			rtn += ",\"shortClassName\":\"" + component.getShortClassName() + "\"";
			rtn += "}";
		}
		rtn = "[" + rtn + "]";
		return rtn;
	}
	public int getRecentTaskNumber() {
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
		List<RecentTaskInfo> tasks = am.getRecentTasks(MAX_NUM, ActivityManager.RECENT_WITH_EXCLUDED);
		return tasks.size();
	}
	public String getRecentTasks() {
		try {
			ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
			List<RecentTaskInfo> tasks = am.getRecentTasks(MAX_NUM, ActivityManager.RECENT_WITH_EXCLUDED);
			Iterator<RecentTaskInfo> iterator = tasks.iterator();
			String rtn = "";
			while (iterator.hasNext()) {
				RecentTaskInfo tInfo = iterator.next();
				if (!rtn.equals("")) rtn += ",";
				rtn += "{";
				rtn += "\"id\":" + tInfo.id;
				try {
					rtn += ",\"intent\":\"" + tInfo.baseIntent.toUri(Intent.URI_INTENT_SCHEME) + "\"";
				} catch (Exception e) {
					rtn += ",\"intent\":\"\"";
				}
				try {
					ComponentName component = tInfo.origActivity;
					rtn += ",\"packageName\":\"" + component.getPackageName() + "\"";
					rtn += ",\"className\":\"" + component.getClassName() + "\"";
					rtn += ",\"shortClassName\":\"" + component.getShortClassName() + "\"";
				} catch (Exception e) {
					rtn += ",\"packageName\":\"\"";
					rtn += ",\"className\":\"\"";
					rtn += ",\"shortClassName\":\"\"";
				}
				rtn += "}";
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
			return "";
		}
	}
	public String getProcessMemoryInfo(int pid) {
		try {
			ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
			Debug.MemoryInfo mi = am.getProcessMemoryInfo(new int[]{pid})[0];
			String rtn = "";
			rtn += "{";
			rtn += "\"totalPrivateDirty\":" + mi.getTotalPrivateDirty();
			rtn += ",\"totalPss\":" + mi.getTotalPss();
			rtn += ",\"totalSharedDirty\":" + mi.getTotalSharedDirty();
			rtn += "}";
			return rtn;
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
			return "";
		}
	}

	//Information about package
	public String getApplicationInfo(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			ApplicationInfo info = pm.getApplicationInfo(packageName, PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			return getJsonApplicationInfo_(mContext, info);
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getActivities(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES | PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			ActivityInfo[] activities = info.activities;
			if (activities == null) return "[]";
			String rtn = "";
			for (int i = 0; i < activities.length; i++) {
				if (i > 0) rtn += ",";
				rtn += getJsonActivityInfo_(mContext, activities[i]);
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getReceivers(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_RECEIVERS | PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			ActivityInfo[] receivers = info.receivers;
			if (receivers == null) return "[]";
			String rtn = "";
			for (int i = 0; i < receivers.length; i++) {
				if (i > 0) rtn += ",";
				rtn += getJsonActivityInfo_(mContext, receivers[i]);
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getProverders(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_PROVIDERS | PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			ProviderInfo[] providers = info.providers;
			if (providers == null) return "[]";
			String rtn = "";
			for (int i = 0; i < providers.length; i++) {
				if (i > 0) rtn += ",";
				rtn += getJsonProviderInfo_(mContext, providers[i]);
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getServices(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SERVICES | PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			ServiceInfo[] services = info.services;
			if (services == null) return "[]";
			String rtn = "";
			for (int i = 0; i < services.length; i++) {
				if (i > 0) rtn += ",";
				rtn += getJsonServiceInfo_(mContext, services[i]);
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getPermissions(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
			PermissionInfo[] permissions = info.permissions;
			if (permissions == null) return "[]";
			String rtn = "";
			for (int i = 0; i < permissions.length; i++) {
				if (i > 0) rtn += ",";
				rtn += getJsonPermissionInfo_(mContext, permissions[i]);
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getUserPermissions(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS | PackageManager.GET_URI_PERMISSION_PATTERNS | PackageManager.GET_UNINSTALLED_PACKAGES);
			String[] userPermissions = info.requestedPermissions;
			if (userPermissions == null) return "[]";
			String rtn = "";
			for (int i = 0; i < userPermissions.length; i++) {
				if (i > 0) rtn += ",";
				rtn += "\"" + userPermissions[i] + "\"";
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getFeatures(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_CONFIGURATIONS | PackageManager.GET_UNINSTALLED_PACKAGES);
			FeatureInfo[] features = info.reqFeatures;
			if (features == null) return "[]";
			String rtn = "";
			for (int i = 0; i < features.length; i++) {
				if (i > 0) rtn += ",";
				rtn += "\"" + features[i].name + "\"";
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getSignatures(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES);
			Signature[] signatures = info.signatures;
			String rtn = "";
			for (int i = 0; i < signatures.length; i++) {
				if (i > 0) rtn += ",";
				rtn += "\"" + signatures[i].toCharsString() + "\"";
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getGIDs(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_GIDS | PackageManager.GET_UNINSTALLED_PACKAGES);
			int[] gids = info.gids;
			if (gids == null) return "[]";
			String rtn = "";
			for (int i = 0; i < gids.length; i++) {
				if (i > 0) rtn += ",";
				rtn += gids[i];
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getSharedLibraryFiles(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			ApplicationInfo info = pm.getApplicationInfo(packageName, PackageManager.GET_SHARED_LIBRARY_FILES | PackageManager.GET_UNINSTALLED_PACKAGES);
			if (info.sharedLibraryFiles == null) return "[]";
			String rtn = "";
			for (int i = 0; i < info.sharedLibraryFiles.length; i++) {
				if (i > 0) rtn += ",";
				rtn += "\"" + info.sharedLibraryFiles[i] + "\"";
			}
			rtn = "[" + rtn + "]";
			return rtn;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getSharedUserId(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
			return info.sharedUserId;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public int getSharedUserLabel(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
			return info.sharedUserLabel;
		} catch (NameNotFoundException e) {
			return -1;
		}
	}
	public int getVersionCode(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
			return info.versionCode;
		} catch (NameNotFoundException e) {
			return -1;
		}
	}
	public String getVersionName(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo info = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
			return info.versionName;
		} catch (NameNotFoundException e) {
			return "";
		}
	}
	public String getEnableSetting(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		switch (pm.getApplicationEnabledSetting(packageName)) {
			case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT :
				return "COMPONENT_ENABLED_STATE_DEFAULT";
			case PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
				return "COMPONENT_ENABLED_STATE_ENABLED";
			case PackageManager.COMPONENT_ENABLED_STATE_DISABLED :
				return "COMPONENT_ENABLED_STATE_DISABLED";
			default :
				return "COMPONENT_ENABLED_STATE_DEFAULT";
		}
	}
	public String getInstaller(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		return pm.getInstallerPackageName(packageName);
	}
	public long getSize(String packageName) {
		return getSize_(mContext, packageName);
	}

	//Launch Intent
	public String getLaunchIntent(String packageName) {
		PackageManager pm = mContext.getPackageManager();
		Intent intent = pm.getLaunchIntentForPackage(packageName);
		if (intent == null) return "";
		String rtn = "{";
		rtn += "\"action\":\"" + intent.getAction() + "\"";
		rtn += ",\"uri\":\"" + intent.toUri(Intent.URI_INTENT_SCHEME) + "\"";
		rtn += ",\"string\":\"" + intent.toString() + "\"";
		rtn += "}";
		return rtn;
	}

}
